package com.tsd.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.tsd.CommonMsgNameConstants;
import com.tsd.CommonParamNameConstants;
import com.tsd.common.dao.CommonFileMapper;
import com.tsd.common.service.CommonFileService;
import com.tsd.common.vo.BatchDeleteLogicVo;
import com.tsd.core.constants.Constants;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.core.vo.ErrorCode;
import com.tsd.core.vo.HlpException;
import com.tsd.core.vo.HttpResult;
import com.tsd.core.vo.PageBean;
import com.tsd.service.BaseServiceImpl;
import com.tsd.system.dao.*;
import com.tsd.system.entity.*;
import com.tsd.system.service.*;
import com.tsd.system.vo.MyUserInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;



/**
 * 描述：SysUser 服务实现层
 *
 * @author Hillpool
 * @date 2019/03/12 12:20:51
 */
@Service
public class SysUserServiceImpl extends BaseServiceImpl implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private CommonFileMapper commonFileMapper;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private SysUserResourceMapper sysUserResourceMapper;
    @Resource
    private SysUserClientMapper sysUserClientMapper;
    @Resource
    private SysAccountSetMapper sysAccountSetMapper;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysUserResourceService sysUserResourceService;
    @Resource
    private SysUserClientService sysUserClientService;
    @Resource
    private SysGroupPersonMapper sysGroupPersonMapper;
    @Resource
    private CommonFileService commonFileService;
    @Resource
    private SysRoleService sysRoleService;

    @Override
    public SysUser getSysUserById(Long id) throws Exception {
        return sysUserMapper.selectByPrimaryKey(id);
    }

    @Override
    public Map<String, Object> getSysUserParamsById(Long id) throws Exception {
        return sysUserMapper.selectParamsById(id);
    }

    @Override
    public SysUserExt queryBySid(String sid) throws Exception {
        return sysUserMapper.selectBySid(sid);
    }

    /**
     * 新账户绑定的员工之前是否已经有绑定其他账户
     *
     * @param newUser
     * @return
     */
    @Override
    public SysUserExt personHasBindOtherUser(SysUserExt newUser) {
        SysUserExt oldUser = null;
        if (!HlpUtils.isEmpty(newUser.getGroup_person_sid())) {
            SysGroupPersonExt personExt = sysGroupPersonMapper.selectBySid(newUser.getGroup_person_sid());
            if (!HlpUtils.isEmpty(personExt.getUser_sid())) {
                oldUser = sysUserMapper.selectBySid(personExt.getUser_sid());
                if (oldUser != null && Constants.DR_VALID == oldUser.getDr()
                        && !personExt.getUser_sid().equals(newUser.getSid())) {
                    return oldUser;
                }
            }
        }
        return null;
    }

    @Override
    public SysUserExt getSysUserByOpenId(String openId) throws Exception {
        SysUserExt t = sysUserMapper.selectSysUserByOpenId(openId);
        return t;
    }

    @Override
    public void saveMyUserInfo(MyUserInfo myUserInfo, SysUser opUser) throws Exception {
        SysUser sysUser = JSON.parseObject(JSON.toJSONString(myUserInfo), SysUser.class);
        SysUser old = sysUserMapper.selectByPrimaryKey(sysUser.getId());
        super.checkEmpty(old, "用户不存在");
        if (!HlpUtils.isEqual(old.getHead_pic(), sysUser.getHead_pic())) {
            commonFileService.deleteCommonFile(opUser, old.getHead_pic());
            commonFileService.updateAssociateData(sysUser.getHead_pic(), SysUserExt.TABLE_NAME, old.getSid(), "head_pic");
        }
        super.autoInjectBaseData(sysUser, opUser, TYPE_UPDATE);
        sysUserMapper.updateByPrimaryKeySelective(sysUser);
    }

    @Override
    public SysUserExt saveSysUser(SysUserExt record, SysUser opUser) throws Exception {
        super.checkEmpty(record.getLogin_id(), "缺少login_id");
        //更新账户表
        if (HlpUtils.isEmpty(record.getId())) {
            int count = sysUserMapper.countByLoginId(record.getLogin_id());
            if (count > 0) {
                throw new HlpException("已存在该账户");
            }
            // 检查用户数限制
            String password = HlpUtils.doMd5(record.getPassword());
            record.setPassword(password);
            super.autoInjectBaseData(record, opUser, TYPE_CREATE);
            sysUserMapper.insertSelective(record);
        } else {
            int count = sysUserMapper.countByLoginIdExcludeId(record);
            if (count > 0) {
                throw new HlpException("已存在该账户");
            }
            sysGroupPersonMapper.removeBindByUserSid(record.getSid());
            super.autoInjectBaseData(record, opUser, TYPE_UPDATE);
            record.setPassword(null);
            sysUserMapper.updateByPrimaryKeySelective(record);
        }
        //更新账户资源表
        List<String> resourseList = null;
        if (!HlpUtils.isEmptyList(record.getResourseList())) {
            resourseList = record.getResourseList();
        }
        sysUserResourceService.saveSysResourceList2User(opUser, record.getSid(), resourseList);
        //更新账户-部门员工绑定表
        record.setGroup_sid("");
        if (!HlpUtils.isEmpty(record.getGroup_person_sid())) {
            SysGroupPersonExt personExt = sysGroupPersonMapper.selectBySid(record.getGroup_person_sid());
            if (personExt != null) {
                personExt.setUser_sid(record.getSid());
                super.autoInjectBaseData(personExt, opUser, this.TYPE_UPDATE);
                sysGroupPersonMapper.updateByPrimaryKeySelective(personExt);
                record.setGroup_sid(personExt.getGroup_sid());
            }
        }
        sysUserMapper.updateByPrimaryKeySelective(record);
        //更新账户角色表
        List<String> roleSidList = record.getRole_sid_list();
        if (roleSidList == null) {
            roleSidList = new ArrayList<>();
        }
        saveSysUserRoleList(record, opUser, roleSidList);
        sysUserClientService.saveSysClientList2User(record, opUser);
        return record;
    }

    @Override
    public void saveSysUser4Sync(SysUser record) throws Exception {
        if (HlpUtils.isEmpty(record.getId())) {
            record.setSid(super.getPrimaryKey());
            if (HlpUtils.isEmpty(record.getCreate_date())) {
                record.setCreate_date(new Date());
            }
            if (HlpUtils.isEmpty(record.getState())) {
                record.setState(Constants.USER_STATUS_VALID);
            }
            if (HlpUtils.isEmpty(record.getDr())) {
                record.setDr(Constants.DR_VALID);
            }
            sysUserMapper.insertSelective(record);
        } else {
            record.setUpdate_date(new Date());
            record.setPassword(null);
            sysUserMapper.updateByPrimaryKeySelective(record);
        }
    }

    @Override
    public void saveSysUserRole(SysUser record, SysUser opUser, SysUserRole sysUserRole) throws Exception {
        sysUserRole.setUser_sid(record.getSid());
        sysUserRoleService.saveSysUserRole(sysUserRole, opUser);
    }

    @Override
    public void saveSysUserRoleList(SysUser record, SysUser opUser, List<String> roleSidList) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("user_sid", record.getSid());
        List<SysUserRoleExt> oldList = sysUserRoleMapper.selectByUserSid(params);
        //不存在角色的编号进行删除
        List<Long> delIds = ListUtil.filterMap(oldList, t -> !roleSidList.contains(t.getRole_sid()), SysUserRoleExt::getId);
        if (!HlpUtils.isEmptyList(delIds)) {
            for (Long id : delIds) {
                sysUserRoleService.deleteLogicalUserRoleById(id, opUser);
            }
        }
        List<String> oldResList = ListUtil.map(oldList, SysUserRoleExt::getRole_sid);
        List<String> addResList = ListUtil.filter(roleSidList, t -> !oldResList.contains(t));
        if (!HlpUtils.isEmptyList(addResList)) {
            List<SysUserRole> insertList = new ArrayList<>();
            for (String resSid : addResList) {
                SysUserRole userRole = new SysUserRole();
                userRole.setUser_sid(record.getSid());
                userRole.setRole_sid(resSid);
                super.autoInjectBaseData(userRole, opUser, this.TYPE_CREATE);
                insertList.add(userRole);
            }
            sysUserRoleMapper.insertList(insertList);
        }

    }

    @Override
    public void deleteSysUser(Long id, SysUser opUser) throws Exception {
        SysUser record = new SysUser();
        record.setId(id);
        super.autoInjectBaseData(record, opUser, TYPE_DELETE);
        sysUserMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public HttpResult<String> batchDeleteSysUser(List<String> sids, SysUser opUser) throws Exception {
        if (HlpUtils.isEmptyList(sids)) {
            return null;
        }
        if (sids.contains(Constants.MASTER_USER_SID)){
            //主账号不能被删除
            return HttpResult.fail(ErrorCode.CODE_PROC_ERROR,CommonMsgNameConstants.MASTER_USER_NO_DELETE);
        }
        SysUserExt params = new SysUserExt();
        params.setDr(0);
        params.setSid_list(sids);
        List<SysUserExt> userExtList = sysUserMapper.selectByEntity(params);

        List<String> userList = ListUtil.map(userExtList, SysUserExt::getSid);
        SysGroupPersonExt ext = new SysGroupPersonExt();
        ext.setDr(0);
        ext.setUser_list(userList);
        List<SysGroupPersonExt> personExtList = sysGroupPersonMapper.selectByEntity(ext);
        if (!HlpUtils.isEmptyList(personExtList)) {
            List<String> sidList = ListUtil.map(personExtList, SysGroupPersonExt::getSid);
            sysGroupPersonMapper.batchUpdateUserBySid(sidList, "");
        }
        BatchDeleteLogicVo logicVo = new BatchDeleteLogicVo(opUser);
        logicVo.setSidList(sids);
        sysUserMapper.deleteLogicBySidList(logicVo);
        return null;
    }

    @Override
    public List<SysUserExt> findSysUsers(Map<String, Object> params, PageBean page) throws Exception {
        List<SysUserExt> list = sysUserMapper.selectByPage(params, page);
        this.procResourceAndClient(list, params);
        return list;
    }

    @Override
    public List<SysUserExt> findSysUsers(Map<String, Object> params) throws Exception {
        List<SysUserExt> list = sysUserMapper.selectByParams(params);
        this.procResourceAndClient(list, params);
        return list;
    }

    private void procResourceAndClient(List<SysUserExt> list, Map<String, Object> params) {
        if (!HlpUtils.isEmptyList(list) && params.containsKey("resource_client")) {
            List<String> userList = ListUtil.map(list, SysUserExt::getSid);
            List<SysUserResourceExt> userResourceExtList = null;
            List<SysUserClientExt> userClientExtList = null;
            if (!HlpUtils.isEmptyList(userList)) {
                userResourceExtList = sysUserResourceMapper.selectByUserList(userList);
                userClientExtList = sysUserClientMapper.selectByUserList(userList);
            }
            for (SysUserExt userExt : list) {
                List<SysUserResourceExt> resourceFilterList = ListUtil.filter(userResourceExtList, t -> userExt.getSid().equals(t.getUser_sid()));
                if (!HlpUtils.isEmptyList(resourceFilterList)) {
                    userExt.setUserResourceList(resourceFilterList);
                }

                List<SysUserClientExt> clientFilterList = ListUtil.filter(userClientExtList, t -> userExt.getSid().equals(t.getUser_sid()));
                if (!HlpUtils.isEmptyList(clientFilterList)) {
                    userExt.setUserClientList(clientFilterList);
                }
            }
        }
    }

    @Override
    public List<Map<String, Object>> findSysUserParams(Map<String, Object> params, PageBean page) throws Exception {
        return sysUserMapper.selectParamsByPage(params, page);
    }

    @Override
    public void resetPwd(String userId, String password) throws Exception {
        SysUser old = sysUserMapper.selectBySid(userId);
        if (old != null) {
            String pwdMd5 = HlpUtils.doMd5(password);
            old.setPassword(pwdMd5);
            sysUserMapper.updateByPrimaryKeySelective(old);
        } else {
            throw new HlpException("账户信息无效");
        }
    }

    @Override
    public HttpResult<String> changePwd(SysUser opUser, String sid, String password, String newPassword) throws Exception {
        SysUser old = sysUserMapper.selectBySid(sid);
        if (old == null) {
            return HttpResult.fail(ErrorCode.CODE_PROC_ERROR, "账户信息无效");
        }
        String pwdMd5 = HlpUtils.doMd5(password);
        if (!HlpUtils.isEqual(old.getPassword(),pwdMd5)) {
            return HttpResult.fail(ErrorCode.CODE_PROC_ERROR,"原密码不符");
        }
        String newPwdMd5 = HlpUtils.doMd5(newPassword);
        if (HlpUtils.isEqual(newPwdMd5,old.getPassword())){
            return HttpResult.fail(ErrorCode.CODE_PROC_ERROR,"新旧密码不能相同");
        }
        old.setPassword(newPwdMd5);
        old.setLast_logined_date(new Date());
        old.setMust_change_pwd(Constants.VALUE_NO+"");
        super.autoInjectBaseData(old, opUser, this.TYPE_UPDATE);
        sysUserMapper.updateByPrimaryKeySelective(old);
        return null;
    }

    @Override
    public List<SysUserExt> queryByMobile(String mobile) throws Exception {
        if (mobile == null) {
            throw new HlpException("手机号为空");
        } else {
            return sysUserMapper.selectByMobile(mobile);
        }
    }

    private boolean isPhoneLogin(String tmn) {
        return "phone".equalsIgnoreCase(tmn) || "android".equalsIgnoreCase(tmn) || "ios".equalsIgnoreCase(tmn);
    }

    @Override
    public SysUserExt checkUserLoginPassword(String loginId, String password) throws Exception {
        super.checkEmpty(loginId, "缺少参数：loginId");
        super.checkEmpty(password, "缺少参数：password");
        SysUserExt user = sysUserMapper.selectByLoginId(loginId.trim());
        if (user != null) {
            if (user.getState() != null && user.getState() == Constants.USER_STATUS_VALID) {
                String md5 = HlpUtils.doMd5(password);
                if (md5.equals(user.getPassword())) {
                    return user;
                }
            }
        }
        return null;
    }

    @Override
    public SysUserExt loginUser(Map<String, Object> map) throws Exception {
        String loginId = HlpUtils.getString(map, CommonParamNameConstants.LOGIN_ID);
        String password = HlpUtils.getString(map, CommonParamNameConstants.PASSWORD);
        super.checkEmpty(loginId, "缺少参数："+CommonParamNameConstants.LOGIN_ID);
        super.checkEmpty(password, "缺少参数："+CommonParamNameConstants.PASSWORD);
        return this.loginUser(loginId, password);
    }

    @Override
    public SysUserExt loginUser(String loginId, String password) throws Exception {
        SysUserExt user = sysUserMapper.selectByLoginId(loginId.trim());
        if (user == null) {
            throw new HlpException("账号或密码错误");
        }
        if (HlpUtils.isEmpty(user.getPassword())) {
            user.setPassword(HlpUtils.doMd5(password));
            sysUserMapper.updateByPrimaryKeySelective(user);
        }
        if (user.getState() != null && user.getState() == Constants.USER_STATUS_VALID) {
            String md5 = HlpUtils.doMd5(password);
            if (user.getPassword() != null && user.getPassword().equals(md5)) {
                user.setPassword(null);
                SysUser u = new SysUser();
                u.setId(user.getId());
                u.setLast_logined_date(new Date());
                sysUserMapper.updateByPrimaryKeySelective(u);
                return user;
            } else {
                throw new HlpException("账号或密码错误");
            }
        } else {
            throw new HlpException("用户状态异常");
        }
    }

    @Override
    public SysUser queryByLoginId(String loginId) throws Exception {
        return sysUserMapper.selectByLoginId(loginId);
    }

    @Override
    public void updateLog(SysUser user) {
        sysUserMapper.updateLoginTime();
    }

    @Override
    public List<SysUserExt> findUserByOrgSid(String orgSid) throws Exception {
        return sysUserMapper.selectByGroupSid(orgSid);
    }

    @Override
    public List<SysUserExt> findSysUsersByParams(Map<String, Object> params) throws Exception {
        return sysUserMapper.selectSysUsersByParams(params);
    }

    @Override
    public List<SysUserExt> findUnBindSysUser(Map<String, Object> params) throws Exception {
        return sysUserMapper.findUnBindSysUser(params);
    }

    @Override
    public List<SysResourceExt> findUserPermission(String userSid, List<String> permission) throws Exception {
        return sysUserMapper.selectUserPermission(userSid, permission);
    }

    @Override
    public HttpResult<String> resetAdmin(String loginId, String password, SysUser opUser) throws Exception {
        SysUserExt t = sysUserMapper.selectByLoginId(loginId);
        boolean has = t != null;
        if (!has) {
            return HttpResult.fail(ErrorCode.CODE_PROC_ERROR, CommonMsgNameConstants.NO_DATA);
        }else{
            String pwdMd5 = HlpUtils.doMd5(password);
            t.setPassword(pwdMd5);
            t.setState(Constants.USER_STATUS_VALID);
            super.autoInjectBaseData(t, opUser, TYPE_UPDATE);
            sysUserMapper.updateByPrimaryKeySelective(t);
        }
        return null;
    }

    @Override
    public int getAccountSetUcLimit(String dataSource) throws Exception {
        SysAccountSetExt accountSetExt = sysAccountSetMapper.selectBySid(dataSource);
        if (accountSetExt == null) {
            throw new HlpException("账套：" + dataSource + "不存在");
        }
        if (HlpUtils.isEmpty(accountSetExt.getUc_limit()) ) {
            return 0;
        }else{
            return accountSetExt.getUc_limit();
        }
    }

    @Override
    public List<SysUserExt> findSysUserBaseInfos(Map<String, Object> params, PageBean page) throws Exception {
        List<SysUserExt> list = sysUserMapper.selectSysUsersByPage(params, page);
        return list;
    }

    @Override
    public List<SysUserExt> findSysUserBaseInfos(Map<String, Object> params) throws Exception {
        List<SysUserExt> list = sysUserMapper.selectSysUsersByParams(params);
        return list;
    }

    @Override
    public void initDefaultAdmin(SysUserExt admin) throws Exception {
        admin.setMust_change_pwd(Constants.VALUE_1);
        this.saveSysUser(admin,null);
        sysRoleService.initRoleAll(admin);
    }

    @Override
    public void logout(SysUser user) throws Exception {
        user.setLogout_date(new Date());
        sysUserMapper.updateLogout(user);
    }
}
